#ifndef _VECTOR2_H
#define _VECTOR2_H

#include <math.h>
#include <assert.h>

class Vector2
{
public:
	float x, y;

	Vector2()
	{
		x = 1;
		y = 1;
	}

	Vector2(int x, int y)
	{
		this->x = (float)x;
		this->y = (float)y;
	}

	Vector2(float x, float y)
	{
		this->x = x;
		this->y = y;
	}

	float length()
	{
		return (float)sqrt((x * x) + (y * y));
	}

	float lengthSquared()
	{
		return ((x * x) + (y * y));
	}

	void normalize()
	{
		float length = this->length();
		x = x / length;
		y = y / length;
	}

	float dotProduct(const Vector2& vector) const
	{
		return x * vector.x + y * vector.y;
	}

	float crossProduct(const Vector2& vector) const
	{
		return x * vector.y - y * vector.x;
	}

	Vector2& operator = (const Vector2& vector)
	{
		x = vector.x;
		y = vector.y;
		return *this;
	}

	bool operator == (const Vector2& vector) const
	{
		return (x == vector.x && y == vector.y);
	}

	bool operator != (const Vector2& vector) const
	{
		return (x != vector.x || y != vector.y );
	}

	Vector2 operator + (const Vector2& vector) const
	{
		return Vector2(x + vector.x, y + vector.y);
	}

	Vector2 operator - (const Vector2& vector) const
	{
		return Vector2(x - vector.x, y - vector.y);
	}

	Vector2 operator * (const float scalar) const
	{
		return Vector2(x * scalar, y * scalar);
	}
	
	Vector2 operator * (const Vector2& vector) const
	{
		return Vector2(x * vector.x, y * vector.y);
	}
	
	Vector2 operator / (const float scalar) const
	{
		assert(scalar != 0.0f);
		float scalarInverse = 1.0f / scalar;
		return Vector2(x * scalarInverse, y * scalarInverse);
	}
	
	Vector2 operator / (const Vector2& vector) const
	{
		return Vector2(x / vector.x, y / vector.y);
	}

	Vector2& operator += (const Vector2& vector)
	{
		x += vector.x;
		y += vector.y;
		
		return *this;
	}

	Vector2& operator -= (const Vector2& vector)
	{
		x -= vector.x;
		y -= vector.y;
		
		return *this;
	}
	
	Vector2& operator *= (const float scalar)
	{
		x *= scalar;
		y *= scalar;

		return *this;
	}

	Vector2& operator *= (const Vector2& vector)
	{
		x *= vector.x;
		y *= vector.y;
		
		return *this;
	}
	
	Vector2& operator /= (const float scalar)
	{
		assert(scalar != 0.0f);
		
		float floatInverse = 1.0f / scalar;
		
		x *= floatInverse;
		y *= floatInverse;
		
		return *this;
	}
	
	Vector2& operator /= (const Vector2& vector)
	{
		x /= vector.x;
		y /= vector.y;
		
		return *this;
	}
};

#endif